/* cl.ext.Nestable 0.1*/
(
    function (factory) {
        if (typeof define === 'function' && define.amd) {
            define(['jquery',"Nestable"], factory);
        } else if (typeof module === 'object' && module.exports) {
            module.exports = function( root, jQuery ) {
                var nestable = require('Nestable');
                if ( jQuery === undefined ) {
                    if ( typeof window !== 'undefined' ) {
                        jQuery = require('jquery');
                    }
                    else {
                        jQuery = require('jquery')(root);
                    }
                }
                factory(jQuery);
            };
        } else {
            factory(jQuery);
        }
    }(
    function ($){
        var defaultExtInfo={
            type:"li",
            dataId:"id",
            data:[],ajax:{url:"",data:{}},//data,ajax 二选一。同时填写优先ajax
            afterAjaxCallback:null,
            initCallback:null,
            changeCallback:null,
            isBindHtml:true,
            isRemove:false
        };
        var defaults={
            group:1,//group相同时可以相互拖动
            maxDepth:1,//层级
            infoExt:defaultExtInfo,
            moveStopCallback:null
        };
        var $modalCommon={
            getDefaults :function () {
                return defaults
            },
            getOptions : function (elementData,options) {
                options=$.ExtCommon.isCheckEmpty(options)?{}:options;
                var optionBase =$.ExtCommon.initMergeJson(elementData,options);
                optionBase =$.ExtCommon.initMergeJson(this.getDefaults(),optionBase);
                if(optionBase.infoExt.type=="tr"){
                    optionBase.listNodeName="table";
                    optionBase.itemNodeName="tr";
                    optionBase.rootClass="table-drag-root";
                    optionBase.listClass="table-drag-list";
                    optionBase.itemClass="table-drag-item";
                    optionBase.placeClass="table-drag-placeholder";
                    optionBase.dragClass="table-drag-hover";
                    optionBase.handleClass="table-drag-handle";
                    optionBase.placeElement=$("<tr><td colspan='5'></td></tr>");
                }
                return optionBase
            },
            getStrHtml:function(options){
                var strlis= $.map(options.infoExt.data,function(info){
                    var strRemove= options.infoExt.isRemove?'<i class="fa fa-remove dd-remove dd-nodrag"></i>':"";
                    return ' <li class="dd-item" data-id="'+info.id+'">'+
                        '<div class="dd-handle">'+info.name+strRemove+'</div>'+
                        '</li>';
                }).join("");
                return '<ol class="dd-list">'+strlis+'</ol>';
            }
        };
        var modalOperateElement=function(element,options){
            this.elementModal = element;
            this.optionModal=options;
        };
        modalOperateElement.prototype = {
            init:function(){
                 this.bindEvent();
            },
            bindEvent:function(){
                var self = this;
                if(!$.ExtCommon.isCheckEmpty(self.elementModal.btnRemove)){
                    self.elementModal.btnRemove.on("click", function () {
                        $(this).parents(".dd-item:first").remove().empty();
                    });
                }
            },
            destroyHtml:function(){
                if(!$.ExtCommon.isCheckEmpty(this.elementModal.btnRemove)){
                    this.elementModal.btnRemove.off();
                    this.elementModal.btnRemove=null;
                }
            }
        };
        var NestableExtModal = function(element, options) {
            var self=this;
            self.element = $(element);
            self.elementContainer={elementType:null, parent:null, children:null};
            self.optionBase=$modalCommon.getOptions(self.element.data(),options);
            self.elementValue={};
            if(!$.ExtCommon.isCheckEmpty(self.optionBase.infoExt.ajax.url)){
                var url=self.optionBase.infoExt.ajax.url;
                var para=self.optionBase.infoExt.ajax.data;
                para= $.ExtCommon.isCheckEmpty(para)?{}:para;
                $.ExtAjax.initGet({url:url,data:para,
                    successCallback:function(res){
                        var list=res.success? res.data:[];
                        if(!res.success){ $.ExtNotify.error(res.msg);}
                        self.optionBase.infoExt.dataOriginal=list;
                        if(self.optionBase.infoExt.afterAjaxCallback){
                            var templist=self.optionBase.infoExt.afterAjaxCallback(list);
                            self.optionBase.infoExt.data= $.ExtCommon.isCheckEmpty(templist)?[]:templist;
                        }else{
                            self.optionBase.infoExt.data=list;
                        }
                        self._init();
                    }
                });
            }else{
                self.optionBase.infoExt.dataOriginal=self.optionBase.infoExt.data;
                self._init();
            }
        };
        NestableExtModal.prototype = {
            _init:function(){
                var self=this;
                self.elementContainer={};
                if(self.optionBase.infoExt.isBindHtml && self.optionBase.infoExt.data.length>0){
                    var strHtml="";
                    var type=self.optionBase.infoExt.type;
                    switch(type){
                        case "li":
                            self.element.addClass("default-dd dd");
                            strHtml=$modalCommon.getStrHtml(self.optionBase);
                            break;
                    }
                    self.element.html(strHtml);
                    if(self.optionBase.infoExt.isRemove){ self.elementContainer.btnRemove=self.element.find(".dd-remove");}
                }
                self.element.nestable(self.optionBase);
                self.elementOperate=new modalOperateElement(self.elementContainer,self.optionBase);
                self.elementOperate.init();
                var values=self.getValue();
                if($.ExtCommon.isCheckEmpty(self.elementValue.original)){self.elementValue.original=values;}
                self.elementValue.last=values;
                if(self.optionBase.infoExt.changeCallback){
                    self.element.off("change").on("change",function () {
                        var moveValue=self.getValue();
                        var isChange=moveValue!=self.elementValue.last;
                        self.elementValue.last=moveValue;
                        self.optionBase.infoExt.changeCallback(isChange,moveValue==self.elementValue.original);
                    });
                }
            },
            getValue:function(){
                var list=this.element.nestable('serialize');
                var paramId=this.optionBase.infoExt.dataId;
                return  $.ExtCommon.isCheckEmpty(list)?"":$.map(list,function(info){return info[paramId]}).join(",");
            },
            getValueInfo:function(){
                var arrValue=this.getValue().split(",");
                var paramId=this.optionBase.infoExt.dataId;
                return arrValue.length==0?[]:$.map(this.optionBase.infoExt.data,function(info){if(arrValue.indexOf(info[paramId].toString())>-1){return info;}});
            },
            refreshData:function(data){
                this.optionBase.infoExt.data=data;
                if(this.elementOperate){this.elementOperate.destroyHtml();}
                this.element.find("ol.dd-list").remove().empty();
                this._init();
            }
        };
        $.fn.ExtNestable = function(options) {
            var dataFun;
            this.each(function() {
                var el = $(this);
                var tempData=el.data('ExtNestable');
                if (tempData) {
                    if (typeof  options == "string") {
                        if (tempData[options]) {
                            dataFun =tempData[options]()
                        } else {
                            dataFun = tempData
                        }
                    } else {
                        dataFun = tempData
                    }
                } else {
                    dataFun = new NestableExtModal(el, options);
                    el.data('ExtNestable', dataFun);
                }
            });
            return dataFun;
        };
        return NestableExtModal;
    })
);
